package com.bosssoft.platform.fasttcc.support;

import com.bosssoft.platform.fasttcc.CompleteStageListener;
import com.bosssoft.platform.fasttcc.RemoteResource;
import com.bosssoft.platform.fasttcc.RemoteResourceFactory;
import com.bosssoft.platform.fasttcc.Xid;
import com.jfireframework.baseutil.TRACEID;
import jdk.nashorn.internal.ir.IfNode;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class OkHttpRemoteResourceFactory extends CachedRemoteResourceFactory
{

    static final         String       NODEIDENTIFIER = "FASTTCC-NODEIDENTIFIER";
    private static final Logger       LOGGER         = LoggerFactory.getLogger(HttpUrlConnectionRemoteResourceFactory.class);
    private final        String       identifier;
    private final        OkHttpClient okHttpClient   = new OkHttpClient();

    public OkHttpRemoteResourceFactory(String identifier)
    {
        this.identifier = identifier;
    }

    @Override
    protected RemoteResource build(String identifier)
    {
        return new OkHttpRemoteResource(identifier);
    }

    class OkHttpRemoteResource extends AbstractRemoteResource
    {

        public OkHttpRemoteResource(String identifier)
        {
            super(identifier);
        }

        @Override
        public void commit(boolean async, Xid xid, final CompleteStageListener listener)
        {
            remoteRequest(xid, listener, commitUrlPrefix, async);
        }

        @Override
        public void rollback(boolean async, Xid xid, final CompleteStageListener listener)
        {
            remoteRequest(xid, listener, rollbackUrlPrefix, async);
        }

        private void remoteRequest(Xid xid, final CompleteStageListener listener, String urlPrefix, boolean async)
        {
            final Request request = new Request.Builder().url(urlPrefix + xid.toString()).header(NODEIDENTIFIER, OkHttpRemoteResourceFactory.this.identifier).build();
            if (async)
            {
                Call call = okHttpClient.newCall(request);
                call.enqueue(new Callback()
                {
                    @Override
                    public void onFailure(Call call, IOException e)
                    {
                        LOGGER.error("远端提交出现未知异常", e);
                        listener.onRemoteFinish(OkHttpRemoteResource.this, false);
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException
                    {
                        String traceId = TRACEID.newTraceId();
                        String result  = response.body().string();
                        if ("success".equals(result))
                        {
                            listener.onRemoteFinish(OkHttpRemoteResource.this, true);
                        }
                        else
                        {
                            listener.onRemoteFinish(OkHttpRemoteResource.this, false);
                        }
                    }
                });
            }
            else
            {
                Call call = okHttpClient.newCall(request);
                try
                {
                    String result = call.execute().body().string();
                    if ("success".equals(result))
                    {
                        listener.onRemoteFinish(this, true);
                    }
                    else
                    {
                        listener.onRemoteFinish(this, false);
                    }
                }
                catch (Throwable e)
                {
                    LOGGER.error("traceId:{} 远端提交出现异常", TRACEID.currentTraceId(), e);
                    listener.onRemoteFinish(this, false);
                }
            }
        }
    }
}
